/** This file is *not* compiled by the Makefile !!
    for educational purposes only :) */

package ch.epfl.lara.pm.analyze

import ch.epfl.lara.pm.ast._

object AltUtil {
   
  def findMatchExpressions(tree: Tree) = fm(tree)

  private def fm(trees: List[Tree]): Stream[Match] = Stream.concat(trees.map(t => fm(t)))

  private def fm(tree: Tree): Stream[Match] = tree match {
    //Containers
    case Program(_, objs, cls, expr) => Stream.concat(fm(objs), fm(cls), fm(expr))
	case ObjectDef(_, extr) => fm(extr)
	case ExtractorDef(_, _, body) => fm(body)
        case ClassDef(_,_, _, _, meths) => fm(meths)
	case ParamDef(_, _) => Stream.empty
	case MethodDef(_, _, _, body) => fm(body)
	case CaseDef(_,_, _, body) => fm(body)
	case VarPattern(_, _) => Stream.empty
	case ClassPattern(_, _) => Stream.empty

	//Expr's
    case Var(_) => Stream.empty
	case True | False => Stream.empty
	case Call(obj, _, args) => Stream.concat(fm(obj), fm(args))
	case Select(obj, _) => fm(obj)
	case If(cond, then, elze) => Stream.concat(fm(cond), fm(then), fm(elze))
	case New(_, args) => fm(args)
	case m @ Match(_, _,cases) => Stream.cons(m, fm(cases))
	case Number(_) => Stream.empty
	case Plus(left, right) => Stream.concat(fm(left), fm(right))
	case Minus(left, right) => Stream.concat(fm(left), fm(right))
	case Prod(left, right) => Stream.concat(fm(left), fm(right))
	case Div(left, right) => Stream.concat(fm(left), fm(right))
	case Mod(left, right) => Stream.concat(fm(left), fm(right))
	case Eq(left, right) => Stream.concat(fm(left), fm(right))
	case Less(left, right) => Stream.concat(fm(left), fm(right))
	case LessEq(left, right) => Stream.concat(fm(left), fm(right))
	case EAnd(left, right) => Stream.concat(fm(left), fm(right))
	case EOr(left, right) => Stream.concat(fm(left), fm(right))
	case NotEq(left, right) => Stream.concat(fm(left), fm(right))
        
        //Formulae
	case f: Formula => Stream.empty
        
        //Types
        case _ => Stream.empty
  }
}
